package com.tarena.luban.worker.server.service.impl;

import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import com.tarena.luban.worker.server.bo.*;
import com.tarena.luban.worker.server.repository.WorkerAreaRepository;
import com.tarena.luban.worker.server.repository.WorkerCategoryRepository;
import com.tarena.luban.worker.server.repository.WorkerRepository;
import com.tarena.luban.worker.server.service.WorkerService;
import com.tarena.passport.protocol.LoginUser;
import com.tarena.passport.sdk.context.SecurityContext;
import com.tarena.tp.attach.server.client.AttachApi;
import com.tarena.tp.attach.server.dto.AttachDTO;
import com.tarena.tp.attach.server.param.AttachUpdateParam;
import com.tarena.tp.attach.server.query.AttachQuery;
import com.tarena.tp.luban.account.server.client.AccountApi;
import com.tarena.tp.luban.account.server.dto.AccountDTO;
import com.tarena.tp.luban.worker.server.common.enums.AuditStatusEnum;
import com.tarena.tp.luban.worker.server.dto.param.IdCardParam;
import com.tarena.tp.luban.worker.server.dto.param.WorkerCreateParam;
import com.tedu.inn.protocol.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class WorkerServiceImpl implements WorkerService {
    @Override
    @Transactional
    public Long create(WorkerCreateParam workerCreateParam) throws BusinessException {
        //1. userId获取
        Long userId=getUserIdFromJwt();
        workerCreateParam.setUserId(userId);
        //2. 校验 idCard phone
        checkPhoneAndIdCard(workerCreateParam);
        //3.新增worker数据 同时包含rpc远程调用
        Long workerId=saveWorker(workerCreateParam);
        //4.新增area 和category
        saveWorkerArea(workerCreateParam);
        saveWorkerCategory(workerCreateParam);
        return workerId;
    }

    private void saveWorkerCategory(WorkerCreateParam workerCreateParam) {
        //保证幂等 使用userId删除 在新增
        workerCategoryRepository.deleteCategory(workerCreateParam.getUserId());
        workerCategoryRepository.saveWorkerCategory(workerCreateParam);
    }

    private void saveWorkerArea(WorkerCreateParam workerCreateParam) {
        workerAreaRepository.deleteArea(workerCreateParam.getUserId());
        workerAreaRepository.saveWorkerArea(workerCreateParam);
    }

    @Autowired
    private WorkerRepository workerRepository;
    @Autowired
    private WorkerAreaRepository workerAreaRepository;
    @Autowired
    private WorkerCategoryRepository workerCategoryRepository;
    @Autowired(required = false)
    private AttachApi attachApi;
    @Autowired(required = false)
    private AccountApi accountApi;
    /**
     * 为什么要保证幂等
     */
    private Long saveWorker(WorkerCreateParam workerCreateParam) {
        //保证幂等 使用userId 先删除注册申请的worker 然后在新增 调用仓储层
        workerRepository.deleteWorkerByUserId(workerCreateParam.getUserId());
        Long workerId=workerRepository.saveWorker(workerCreateParam);
        //组织一个远程调用的参数list集合 参数核心内容 业务类型 业务id 图片id
        List<AttachUpdateParam> updateParams=new ArrayList<>();
        List<IdCardParam> attachList = workerCreateParam.getAttachList();
        for (IdCardParam idCardParam : attachList) {
            AttachUpdateParam attachUpdateParam=new AttachUpdateParam();
            attachUpdateParam.setId(idCardParam.getId());
            //100 师傅相关图片 200 用户相关图片 300 订单相关图片 400 商品相关图片 500 其它图片...
            attachUpdateParam.setBusinessType(100);
            attachUpdateParam.setBusinessId(workerId.intValue());
            //保证isCover不空
            attachUpdateParam.setIsCover(1);
            updateParams.add(attachUpdateParam);
        }
        //调用
        int i = attachApi.batchUpdateAttachByIdList(updateParams);
        log.info("受影响的图片数据:{}个",i);
        return workerId;
    }

    private void checkPhoneAndIdCard(WorkerCreateParam workerCreateParam) {
        //TODO 如果出现问题,需要抛出异常
        log.info("测试阶段,检查电话号码和身份证号");
    }

    private Long getUserIdFromJwt() throws BusinessException {
        //调用 私服封装api方法 ,包装了解析头的过程
        LoginUser loginUser = SecurityContext.getLoginToken();
        //如果为空
        if (loginUser==null){
            //抛自定义的业务异常
            throw new BusinessException("-999","user没登录");
        }
        return loginUser.getUserId();
    }

    //和师傅查询有关的方法
    @Override
    public WorkerBO detail() throws BusinessException {
        //1. userId获取 作为查询条件
        //2. 查询worker数据
        //3. 判断 worker不一定能查到
        //3.1 查到 worker不为空area categroy accountBO attachInfoList
        //3.2 查不到 手动封装一个由参数数据的workerBO对象
        Long userId = getUserIdFromJwt();
        WorkerBO workerBO=workerRepository.getWorkerByUserId(userId);
        //这里workerBO在仓储层不可能返回null
        if (workerBO.getId()==null){
            //封装一个登录但是未申请入驻的师傅数据
            workerBO=new WorkerBO();
            //审核状态 是3 表示当前worker不存在 登录用户没有申请
            workerBO.setAuditStatus(AuditStatusEnum.UNCREATED.getValue());
            //accountBO
            AccountBO accountBO=new AccountBO();
            accountBO.setTotalAmount(0L);
            workerBO.setAccountBO(accountBO);
        }else{
            List<WorkerAreaBO> areaBOS=workerAreaRepository.getAreasByUserId(userId);
            workerBO.setWorkerAreaBOList(areaBOS);
            List<WorkerCategoryBO> categoryBOS=workerCategoryRepository.getCatsByUserId(userId);
            workerBO.setWorkerCategoryBOList(categoryBOS);
            //暂时无法实现account账号的远程调用,给一个假数据
            AccountDTO accountDTO = accountApi.getAccountByUserId(userId);
            AccountBO accountBO=new AccountBO();
            accountBO.setTotalAmount(accountDTO.getTotalAmount());
            workerBO.setAccountBO(accountBO);
            //attachList 使用buzType+buzId 查询图片信息
            List<AttachInfoBO> attachInfos=getWorkerAttach(100,workerBO.getId());
            //审核状态 0 1 2 从数据库查询到的 判断当前workerBO查询中的
            if (workerBO.getAuditStatus()==0){
                //TODO 查询 auditLog 获取这个师傅的最后一条拒绝的日志 补充
            }
        }
        return workerBO;
    }

    private List<AttachInfoBO> getWorkerAttach(int businessType, Long businessId) {
        //1.按照接口 入参 封装query对象
        AttachQuery attachQuery=new AttachQuery();
        attachQuery.setBusinessId(businessId.intValue());
        attachQuery.setBusinessType(businessType);
        //2.远程调用执行获取返回结果
        List<AttachDTO> attachDTOS = attachApi.getAttachInfoByParam(attachQuery);
        //3.返回结果 转化一下
        List<AttachInfoBO> attachInfoBOS=new ArrayList<>();
        //远程调用使用师傅业务 师傅id查询图片未必能查到
        if (CollectionUtils.isNotEmpty(attachDTOS)){
            //远程调用非空
            for (AttachDTO attachDTO : attachDTOS) {
                //每一个attachnInfoBO 数据都表示一个图片连接 一般情况下 url包括2部分内容
                //第一部分 访问路径 http://image.jd.com/a/b/c
                //第二部分 图片名称 abcdsdlfsldkfhsladf.jpg
                //两部分拼接 http://image.jd.com/a/b/c/abcdsdlfsldkfhsladf.jpg
                //http://localhost:8092/static/
                String url="http://localhost:8092/static/"+attachDTO.getFileUuid();
                log.info("当前worker师傅拿到绑定图片:{}",url);
                AttachInfoBO attachInfoBO=new AttachInfoBO();
                attachInfoBO.setUrl(url);
                attachInfoBOS.add(attachInfoBO);
            }
        }
        return attachInfoBOS;
    }


}
